﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AudiPyme.DAL
{
    public static class VulnerabilidadesFactory
    {
        //Inserta una vulnerabilidad en la base de conocimiento
        public static void InsertarVulnerabilidad(Vulnerabilidades v)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            agenteBD.AddToVulnerabilidadesEstablecer(v);
            agenteBD.SaveChanges();
        }

        //Indica si hay alguna vulnerabilidad cuyo nombre coincida con el contenido en NVulnerabilidad
        public static bool EstaVulnerabilidad(String NVulnerabilidad)
        {
            bool esta = false;
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> VulnerabilidadIgual = from Vulnerabilidad in agenteBD.VulnerabilidadesEstablecer
                                                     select Vulnerabilidad.Vulnerabilidad;
            foreach (String v in VulnerabilidadIgual)
            {
                if (NVulnerabilidad.Equals(v.Trim(), StringComparison.OrdinalIgnoreCase))
                {
                    esta = true;
                }
            }
            return esta;
        }

        //Devuelve el número de vulnerabilidades totales que hay en la base de conocimiento
        public static int VulnerabilidadesTotales()
        {
            int numeroVulnerabilidades = 0;
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<Vulnerabilidades> VulnTotal = from Vuln in agenteBD.VulnerabilidadesEstablecer
                                                     select Vuln;
            foreach (Vulnerabilidades Vuln in VulnTotal)
            {
                numeroVulnerabilidades++;
            }
            return numeroVulnerabilidades;
        }

        //Devuelve el nombre de la vulnerabilidad asociada a su identificador
        public static String NombreVulnerabilidad(int IdVulnerabilidad)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> NombreVulnerab = from NVulnerabilidad in agenteBD.VulnerabilidadesEstablecer
                                                where NVulnerabilidad.IdVulnerabilidad == IdVulnerabilidad
                                                select NVulnerabilidad.Vulnerabilidad;
            if (NombreVulnerab.Count() == 0)
            {
                return "";
            }
            else
            {
                return NombreVulnerab.First();
            }
        }

        //Método que recoge las Vulnerabilidades que están actualmente disponibles en la Base de Conocimiento
        public static IQueryable<Vulnerabilidades> RecogeVulnerabilidades()
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<Vulnerabilidades> Vulnerabilidades = from Vuln in agenteBD.VulnerabilidadesEstablecer
                                                            where Vuln.Actual == true
                                                            select Vuln;
            if (Vulnerabilidades.Count() == 0)
            {
                return null;
            }
            return Vulnerabilidades;
        }

        //Devuelve un conjunto de vulnerabilidades cuyo nombre contenga la secuencia que almacena TextoBuscar
        public static IQueryable<Vulnerabilidades> RecogeVulnerabilidadesTexto(String TextoBuscar)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<Vulnerabilidades> Vulnerabilidades = from v in agenteBD.VulnerabilidadesEstablecer
                                                            where v.Vulnerabilidad.Contains(TextoBuscar) && v.Actual == true
                                                            select v;
            if (Vulnerabilidades.Count() == 0)
            {
                return null;
            }
            return Vulnerabilidades.OrderBy(v => v.IdVulnerabilidad);
        }

        //Método que actualiza una vulnerabilidad de la base de conocimiento
        public static void ActualizaVulnerabilidad(int IdVulnerabilidad, string Vulnerabilidad)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            var VulnActualiz = (from Vuln in agenteBD.VulnerabilidadesEstablecer
                                where Vuln.IdVulnerabilidad == IdVulnerabilidad
                                select Vuln).Single();
            VulnActualiz.Vulnerabilidad = Vulnerabilidad;
            agenteBD.SaveChanges();
        }


        //Método que hace un borrado lógico de una Vulnerabilidad asi como de todos los elementos de las Tablas depedientes de él en la BD
        public static void EliminaVulnerabilidad(int IdVulnerabilidad)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            Vulnerabilidades VulnerabElim = (from Vuln in agenteBD.VulnerabilidadesEstablecer
                                             where Vuln.IdVulnerabilidad == IdVulnerabilidad
                                             select Vuln).Single();
            VulnerabElim.Actual = false;
            agenteBD.SaveChanges();
            //Estructuras para recoger los elementos a eliminar
            //Lista de Relaciones Tipo Activo - Vulnerabilidades por Criterio de Riesgo
            List<Matriz_TiposActivosVulnerabilidades> LRelTipActVulnPorVuln = new List<Matriz_TiposActivosVulnerabilidades>();
            //Lista de Relaciones Amenaza - Vulnerabilidaes por relaciones de ese tipo
            List<Matriz_AmenazasVulnerabilidades> LRelAmenVulPorVuln = new List<Matriz_AmenazasVulnerabilidades>();
            List<InstanciaTiposActivosVulnerabilidades> LInstPorRelTipActVul = new List<InstanciaTiposActivosVulnerabilidades>();
            //Recorremos todas las tablas por niveles de dependencia con el Criterio de Riesgo eliminado y actualizamos Actual
            //Nivel 1 de Dependencia: Matriz Tipo Activo - Vulnerabilidades
            LRelTipActVulnPorVuln = Matriz_TiposActivosVulnerabilidadesFactory.EliminaRelacionesTipActVulnPorVulnerabilidad(IdVulnerabilidad);
            LRelAmenVulPorVuln = Matriz_AmenazasVulnerabilidadesFactory.EliminaRelacionesPorVulnerabilidad(IdVulnerabilidad);
            //Nivel 2 de Dependencia
            if (LRelTipActVulnPorVuln.Count != 0)
            {
                //Instancia_TiposActivosAmenazasCriteriosRiesgo
                LInstPorRelTipActVul = InstanciaTiposActivosVulnerabilidadesFactory.EliminaInstanciaPorRelacTipActVuln(LRelTipActVulnPorVuln);
            }
        }


        //Método que Restaura el conocimiento asociado a una lista de Vulnerabilidades
        public static void RestauraVulnerabilidad(List<int> LVulnerabilidades)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            foreach (int IdVulnerabilidad in LVulnerabilidades)
            {
                Vulnerabilidades VulnerabRestaurar = (from Vuln in agenteBD.VulnerabilidadesEstablecer
                                                      where Vuln.IdVulnerabilidad == IdVulnerabilidad
                                                      select Vuln).Single();
                VulnerabRestaurar.Actual = true;
            }
            agenteBD.SaveChanges();
            //Estructuras para recoger los elementos a eliminar
            //Lista de Relaciones Tipo Activo - Vulnerabilidades por Criterio de Riesgo
            List<Matriz_TiposActivosVulnerabilidades> LRelTipActVulnPorVuln = new List<Matriz_TiposActivosVulnerabilidades>();
            //Lista de Relaciones Amenaza - Vulnerabilidaes por relaciones de ese tipo
            List<Matriz_AmenazasVulnerabilidades> LRelAmenVulPorVuln = new List<Matriz_AmenazasVulnerabilidades>();
            List<InstanciaTiposActivosVulnerabilidades> LInstPorRelTipActVul = new List<InstanciaTiposActivosVulnerabilidades>();
            //Recorremos todas las tablas por niveles de dependencia con el Criterio de Riesgo eliminado y actualizamos Actual
            //Nivel 1 de Dependencia: Matriz Tipo Activo - Vulnerabilidades
            LRelTipActVulnPorVuln = Matriz_TiposActivosVulnerabilidadesFactory.RestauraRelacionesPorVulnerabilidad(LVulnerabilidades);
            LRelAmenVulPorVuln = Matriz_AmenazasVulnerabilidadesFactory.RestauraRelacionesPorVulnerabilidad(LVulnerabilidades);
            //Nivel 2 de Dependencia
            if (LRelTipActVulnPorVuln.Count != 0)
            {
                //Instancia_TiposActivosVulnerabilidades
                LInstPorRelTipActVul = InstanciaTiposActivosVulnerabilidadesFactory.RestauraInstanciaPorRelacTipActVuln(LRelTipActVulnPorVuln);
            }
        }

        //Devuelve el identificador asociado al nombre de una vulnerabilidad
        public static int IdVulnerabilidad(string VulnerabilidadSelec)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<int> IdVulnerabilidad = from Vuln in agenteBD.VulnerabilidadesEstablecer
                                               where Vuln.Vulnerabilidad.Equals(VulnerabilidadSelec)
                                               select Vuln.IdVulnerabilidad;
            if (IdVulnerabilidad.Count() == 0)
                return 0;
            else
                return IdVulnerabilidad.First();
        }

        //Restaura una lista de vulnerabilidades en la base de conocimiento
        internal static void RestauraVulnerabilidadPorRelaciones(List<int> LIdsVulnerabilidades)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            foreach (int IdVulnerabilidad in LIdsVulnerabilidades)
            {
                //Restauramos la Amenaza
                Vulnerabilidades VulnRestaurar = (from Vuln in agenteBD.VulnerabilidadesEstablecer
                                                  where Vuln.IdVulnerabilidad == IdVulnerabilidad
                                                  select Vuln).Single();
                VulnRestaurar.Actual = true;
            }
            agenteBD.SaveChanges();
        }

        //Inserta una vulnerabilidad en la base de conocimiento parametrizado por su nombre
        public static void InsertarVulnerabilidad(string VulnerabilidadTexto)
        {
            //Recogemos el valor de Vulnerabilidad
            Vulnerabilidades VulnerabilidadNueva = new Vulnerabilidades();
            VulnerabilidadNueva.Vulnerabilidad = VulnerabilidadTexto;
            //Ponemos el campo de Actual a true
            VulnerabilidadNueva.Actual = true;
            //Llamamos al método de inserción
            VulnerabilidadesFactory.InsertarVulnerabilidad(VulnerabilidadNueva);
        }

        //Devuelve el número de vulnerabilidades actualmente disponibles en la base de conocimiento
        public static int NumeroVulnerabilidades()
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int NVulnerabilidades = (from Vuln in agenteBD.VulnerabilidadesEstablecer
                                     where Vuln.Actual == true
                                     select Vuln).Count();
            return NVulnerabilidades;
        }

        //Devuelve el conjunto de las vulnerabilidades deshabilitadas en la base de conocimiento
        public static List<Vulnerabilidades> VulnerabilidadesEliminadas()
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<Vulnerabilidades> LVulnerabilidades = new List<Vulnerabilidades>();
            IQueryable<Vulnerabilidades> VulnQuery = (from v in agenteBD.VulnerabilidadesEstablecer
                                                      where v.Actual == false
                                                      orderby v.IdVulnerabilidad
                                                      select v).Distinct();
            if (VulnQuery.Count() != 0)
            {
                LVulnerabilidades = VulnQuery.ToList();
            }
            return LVulnerabilidades;
        }

        //Devuelve el conjunto de vulnerabilidades deshabilitadas de la base de conocimiento cuyos nombres contengan la secuencia
        //almacenada en TextoBuscar
        public static List<Vulnerabilidades> VulnerabilidadesEliminadasPorVulnerabilidad(string TextoBuscar)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<Vulnerabilidades> LVulnerabilidades = new List<Vulnerabilidades>();
            IQueryable<Vulnerabilidades> VulnQuery = (from v in agenteBD.VulnerabilidadesEstablecer
                                                      where v.Actual == false && v.Vulnerabilidad.Contains(TextoBuscar)
                                                      orderby v.IdVulnerabilidad
                                                      select v).Distinct();
            if (VulnQuery.Count() != 0)
            {
                LVulnerabilidades = VulnQuery.ToList();
            }
            return LVulnerabilidades;
        }
    }
}
